package com.qianying.utils;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.qianying.domain.MapResult;
import com.qianying.domain.StringResult;
import com.qianying.exception.BusinessException;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

@NoArgsConstructor
@Component
public class DataHelper {

    @Autowired
    private ObjectMapper objectMapper;

    /**
     * 2个类相同属性复制
     * @param target
     * @param source
     */
    public  void objCopyPropertiesThrow(Object source,Object target )
    {
        String err = null;

        try {

            BeanUtils.copyProperties(source,target);

        }catch (Exception ex)
        {
            err = ex.getMessage();
        }


        if(err!=null)
        {
            throw  new BusinessException(err);
        }
    }

    /**
     * 2个类相同属性复制
     * @param target
     * @param source
     */
    public  String objCopyProperties(Object source,Object target )
    {
        String err = null;

        try {

            BeanUtils.copyProperties(source,target);

        }catch (Exception ex)
        {
            err = ex.getMessage();
        }

        return  err;
    }

    /**
     * 返回类型非List的数据 没有经过测试
     * @param dataMap
     */
    public Map<String,Object> mapGetNoListClassData(Map<String,Object> dataMap){

        Map<String,Object> curMap = new HashMap<>();

        for(Map.Entry<String,Object> item : dataMap.entrySet()){

            if( item.getValue() instanceof LinkedHashMap) {
                continue;
            }

            curMap.put(item.getKey(),item.getValue());
        }

        return  curMap;

    }

    /**
     * destMap 复制到 sourceMap
     * @param sourceMapList
     * @param destMapList
     */
    public void mapDestCopyToSourceList(List<Map<String,Object>> sourceMapList , List<Map<String,Object>> destMapList)
    {
        if(sourceMapList == null  || destMapList == null )
        {
            return;
        }

        sourceMapList.clear();

        for (Map<String,Object> mapItem : destMapList   )
        {
            sourceMapList.add(mapItem);
        }

    }

    /**
     * destMap 复制到 sourceMap
     * @param sourceMap
     * @param destMap
     */
    public void mapDestCopyToSource(Map<String,Object> sourceMap , Map<String,Object> destMap)
    {
        if(sourceMap == null  || destMap == null )
        {
            return;
        }

        sourceMap.clear();

        for (Map.Entry<String,Object> item : destMap.entrySet())
        {
            sourceMap.put(item.getKey(),item.getValue());
        }
    }

    /**
     * Map连接成 key = value And key = value
     * @param whereCondition
     * @return
     */
    public String mapToWhereCondition(Map<String,Object> whereCondition)
    {
        String condition = "";

        List<String> conditionList = new ArrayList<>();

        for (Map.Entry<String,Object> item : whereCondition.entrySet())
        {

        }

        return  condition;
    }

    /**
     * 包含try toJson
     * @param obj
     * @return
     */
    public String objToJsonStr( Object obj )
    {

        String jsonStr = "";

        try {

            jsonStr = objectMapper.writeValueAsString(obj);

        }catch (Exception e)
        {
            jsonStr = null;
        }

        return jsonStr;
    }

    /**
     * 包含try toJson
     * @param obj
     * @return
     */
    public StringResult objToJsonTryResult(Object obj )
    {
        StringResult stringResult = new StringResult();

        try {

            stringResult.setStr(objectMapper.writeValueAsString(obj));

        }catch (Exception e)
        {
            stringResult.setStr(null);
            stringResult.setException(e);
        }

        return stringResult;
    }

    /**
     * 反序列化
     * @param json
     * @return
     */
    public MapResult jsonToMap(String json ) {

        MapResult mapResult = MapResult.builder().build();

        try {

            Map<String,Object>  dataMap = objectMapper.readValue(json,Map.class);

        }catch ( Exception ex)
        {
            mapResult.setErr(ex.getMessage());
        }

        return  mapResult;

    }

    /**
     * 反序列化
     * @param json
     * @return
     */
    public Map<String,Object> jsonToMapThrow( String json  ){

        Map<String,Object>  dataMap = new HashMap<>();

        String err = null;

        try {

            dataMap = objectMapper.readValue(json,Map.class);

        }catch ( Exception ex)
        {
            err = ex.getMessage() ;
        }

        if( err != null ) {
            throw  new BusinessException(-2,err);
        }

        return  dataMap;

    }

    /**
     * 抓换成map
     * @param obj
     * @return
     */
    public Map<String,Object> objToMapThrow(Object obj){

        Map<String,Object>  dataMap = new HashMap<>();

        String err = null;

        try {

            String jsonStr = objectMapper.writeValueAsString(obj);

            dataMap = objectMapper.readValue( jsonStr ,Map.class);

        }catch ( Exception ex)
        {
            err = ex.getMessage() ;
        }

        if( err != null ) {
            throw  new BusinessException(-2,err);
        }

        return  dataMap;

    }


    /**
     * 驼峰转换_字段成形式 例如:  userName => user_name
     * @param camelCaseMap
     * @return
     */
    public void mapCamelCaseToSnakeCaseSelf(Map<String,Object> camelCaseMap)
    {
        if(camelCaseMap == null || camelCaseMap.size() <= 0 )
        {
            return;
        }

        Map<String,Object> snakeCaseMap = mapCamelCaseToSnakeCase(camelCaseMap);

        camelCaseMap.clear();

        for ( Map.Entry<String,Object> item : snakeCaseMap.entrySet() )
        {
            camelCaseMap.put( item.getKey(),item.getValue() );
        }

    }

    /**
     * 驼峰转换_字段成形式 例如:  userName => user_name
     * @param camelCaseMap
     * @return
     */

    public Map<String,Object> mapCamelCaseToSnakeCase(Map<String,Object> camelCaseMap)
    {
        Map<String,Object> snakeCaseMap  = new HashMap<>();

        if(camelCaseMap == null || camelCaseMap.size() <= 0 )
        {
            return snakeCaseMap;
        }

        for (Map.Entry<String, Object> camelCaseMapItem : camelCaseMap.entrySet())
        {
            String camelCaseName = camelCaseMapItem.getKey();

            List<Integer> upperCaseList = new ArrayList<>();

            for (int i = 0; i < camelCaseName.length(); i++ ) {

                char ch = camelCaseName.charAt(i);

                if ( Character.isUpperCase(ch) ) {
                    upperCaseList.add(i);
                }
            }

            if(upperCaseList.size() <= 0)
            {
                snakeCaseMap.put(camelCaseName,camelCaseMapItem.getValue());
                continue;
            }

            List<String> itemNameList = new ArrayList<>();

            int startIndex = 0 ;

            for (Integer  i : upperCaseList )
            {
                String itemName = camelCaseName.substring(startIndex,i);

                startIndex = i ;

                itemNameList.add(itemName.toLowerCase());
            }

            //补全最后一个
            itemNameList.add( camelCaseName.substring(startIndex).toLowerCase() );

            String snakeCaseName = String.join("_",itemNameList);

            snakeCaseMap.put(snakeCaseName,camelCaseMapItem.getValue());

        }

        return  snakeCaseMap;
    }

    /**
     * 驼峰转换_字段成形式 例如:  userName => user_name
     * @param camelCaseMapList
     * @return
     */
    public List<Map<String,Object>> mapCamelCaseToSnakeCase(List<Map<String,Object>> camelCaseMapList)
    {
        List<Map<String,Object>> snakeCaseMapList  = new ArrayList<>();

        for (Map<String,Object> item : camelCaseMapList)
        {
            snakeCaseMapList.add( mapCamelCaseToSnakeCase(item) );
        }

        return snakeCaseMapList;
    }


    /**
     * 驼峰转换_字段成形式 例如:  userName => user_name
     * @param camelCaseName
     * @return
     */
    public String strCamelCaseToSnakeCase( String camelCaseName )
    {

        List<Integer> upperCaseList = new ArrayList<>();

        for (int i = 0; i < camelCaseName.length(); i++ ) {

            char ch = camelCaseName.charAt(i);

            if ( Character.isUpperCase(ch) ) {
                upperCaseList.add(i);
            }
        }

        if(upperCaseList.size() <= 0)
        {
            return  camelCaseName;
        }

        List<String> itemNameList = new ArrayList<>();

        int startIndex = 0 ;

        for (Integer  i : upperCaseList )
        {
            String itemName = camelCaseName.substring(startIndex,i);

            startIndex = i ;

            itemNameList.add(itemName.toLowerCase());
        }

        //补全最后一个
        itemNameList.add( camelCaseName.substring(startIndex).toLowerCase() );

        String snakeCaseName = String.join("_",itemNameList);

        return snakeCaseName;

    }

    /**
     * 驼峰转换_字段成形式 例如:  userName => user_name
     * @param camelCaseNameList
     * @return
     */
    public List<String> strCamelCaseToSnakeCase ( List<String> camelCaseNameList )
    {
        List<String> snakeCaseList = new ArrayList<>();

        for(String camelCaseItem : camelCaseNameList)
        {
            snakeCaseList .add(  strCamelCaseToSnakeCase (camelCaseItem) );
        }

        return  snakeCaseList;
    }

    /**
     * 驼峰转换_字段成形式 例如:  user_name => userName
     * @param snakeCaseMap
     * @return
     */
    public void mapSnakeCaseToCamelCaseSelf(Map<String,Object> snakeCaseMap)
    {
        if(snakeCaseMap == null || snakeCaseMap.size() <= 0 ){
            return;
        }

        Map<String,Object> camelCaseSMap = mapSnakeCaseToCamelCase( snakeCaseMap );

        snakeCaseMap.clear();

        for ( Map.Entry<String,Object> item : camelCaseSMap.entrySet() )
        {
            snakeCaseMap.put( item.getKey(),item.getValue() );

        }
    }

    public void mapSnakeCaseToCamelCaseSelf(List<Map<String,Object> > snakeCaseMapList)
    {
        for (Map<String,Object> item  : snakeCaseMapList )
        {
            mapSnakeCaseToCamelCaseSelf(item);
        }
    }

    /**
     * _字段转换成驼峰形式 例如:user_name => userName
     * @param mapData
     * @return
     */

    public Map<String,Object> mapSnakeCaseToCamelCase(Map<String,Object> mapData)
    {
        Map<String,Object> objectMap  = new HashMap<>();

        for (Map.Entry<String, Object> item : mapData.entrySet())
        {
            List<String> arry = Arrays.asList(item.getKey().split("_"));

            if(arry.size() == 1)
            {
                objectMap.put(item.getKey(),item.getValue());
                continue;
            }

            List<String> camelCaseNameList  = new ArrayList<>();
            camelCaseNameList.add(arry.get(0).toLowerCase());

            for (String itemStr : arry.subList(1,arry.size()) )
            {
                if(itemStr.length() == 1)
                {
                    camelCaseNameList.add(itemStr.toUpperCase());
                }
                else
                {
                    String camelCaseName =   itemStr.substring(0, 1).toUpperCase() + itemStr.substring(1);
                    camelCaseNameList.add(camelCaseName);
                }
            }

            String newKeyName = String.join("",camelCaseNameList);

            objectMap.put(newKeyName,item.getValue());

        }

        return  objectMap;
    }

    /**
     * _字段转换成驼峰形式 例如:user_name => userName
     * @param mapDataList
     * @return
     */
    public List<Map<String,Object>> mapSnakeCaseToCamelCaseList(List<Map<String,Object>> mapDataList)
    {
        List<Map<String,Object>> objMapList = new ArrayList<>();

        for( Map<String,Object> itemMap : mapDataList)
        {
            Map<String,Object> objMapMap = mapSnakeCaseToCamelCase(itemMap);

            objMapList.add(objMapMap);
        }

        return  objMapList;
    }

    /**
     * 剔除Value为null的值
     * @param mapData
     */
    public void mapFilterNullValue(Map<String,Object> mapData)
    {
        if(mapData == null || mapData.size() <=0)
        {
            return ;
        }

        List<String> keyList = new ArrayList<>();

        for (Map.Entry<String, Object> item : mapData.entrySet())
        {
            if( item.getValue() == null )
            {
                keyList.add(item.getKey());
                continue;
            }
        }

        for (String item : keyList)
        {
            mapData.remove(item);
        }


    }

    /**
     * 剔除Value为null的值和""空串
     * @param mapData
     */
    public void mapFilterNullValueAndEmpty(Map<String,Object> mapData)
    {

        if(mapData == null || mapData.size() <=0)
        {
            return ;
        }

        List<String> keyList = new ArrayList<>();

        for (Map.Entry<String, Object> item : mapData.entrySet())
        {
            if( item.getValue() == null || StringUtils.isEmpty( item.getValue().toString() ) )
            {
                keyList.add(item.getKey());
                continue;
            }
        }

        for (String item : keyList)
        {
            mapData.remove(item);
        }

    }

    /**
     * 针对自身的Map剔除指定的keyList
     * @param mapData
     */
    public void MapFilterSelf(Map<String,Object> mapData, List<String> keyList)
    {
        if(mapData == null || mapData.size() <=0 || keyList == null || keyList.size() <= 0 )
        {
            return ;
        }

        List<String> delList = new ArrayList<>();

        for (Map.Entry<String, Object> item : mapData.entrySet())
        {
            String keyName = item.getKey().toLowerCase();

            for (String itemKey : keyList)
            {
                String itemName = itemKey.toLowerCase();

                if( keyName.equals( itemName ) )
                {
                    delList.add(item.getKey());
                    break;
                }

            }

        }

        for (String item : delList)
        {
            mapData.remove(item);
        }

    }

    /**
     * 获取剔除指定的keyList的新Map不影响原map
     * @param mapData
     */
    public Map<String,Object> MapFilter(Map<String,Object> mapData,List<String> keyList)
    {
        if(mapData == null || mapData.size() <=0 || keyList == null || keyList.size() <= 0 )
        {
            return  new HashMap<>();
        }

        Map<String,Object> filterMap = new HashMap<>();

        List<String> delList = new ArrayList<>();

        for (Map.Entry<String, Object> item : mapData.entrySet())
        {
            filterMap.put(item.getKey(),item.getValue());

            String keyName = item.getKey().toLowerCase();

            for (String itemKey : keyList)
            {
                String itemName = itemKey.toLowerCase();

                if( keyName.equals( itemName ) )
                {
                    delList.add(item.getKey());
                    break;
                }

            }

        }

        for (String item : delList)
        {
            filterMap.remove(item);
        }

        return  filterMap;
    }

    /**
     * 剔除指定的keyList
     * @param mapData
     */
    public Map<String,Object> MapFilterReturnFilterMap(Map<String,Object> mapData,List<String> keyList)
    {
        if(mapData == null || mapData.size() <=0 || keyList == null || keyList.size() <= 0 )
        {
            return new HashMap<>();
        }

        List<String> delList = new ArrayList<>();

        Map<String,Object> mapFilter = new HashMap<>();

        for (String itemKey : keyList)
        {
            String itemName = itemKey.toLowerCase();

            for (Map.Entry<String, Object> item : mapData.entrySet())
            {
                String keyName = item.getKey().toLowerCase();

                if( keyName.equals( itemName ) )
                {
                    delList.add(item.getKey());
                    mapFilter.put(item.getKey(),item.getValue());
                    break;
                }
            }

        }

        for (String item : delList)
        {
            mapData.remove(item);
        }

        return  mapFilter;
    }

    /**
     * 获取指定的keyList
     * @param mapData
     */
    public Map<String,Object> mapGetKeyList(Map<String,Object> mapData,List<String> keyList)
    {
        Map<String,Object> objectMap  = new HashMap<>();

        for (String itemKey : keyList)
        {
            String itemName = itemKey.toLowerCase();

            for (Map.Entry<String, Object> item : mapData.entrySet())
            {
                String keyName = item.getKey().toLowerCase();

                if( itemName.equals( keyName ) )
                {
                    objectMap.put(item.getKey(),item.getValue());
                    break;
                }
            }
        }

        return objectMap;

    }

    /**
     * 获取不在这些字段里面的数据
     * @param mapData
     */
    public Map<String,Object> mapGetKeyNotInList(Map<String,Object> mapData, List<String> keyList)
    {
        Map<String,Object> objectMap  = new HashMap<>();

        for (Map.Entry<String, Object> item : mapData.entrySet())
        {
            objectMap.put(item.getKey(),item.getValue());
        }

        for (String itemKey : keyList)
        {
            objectMap.remove(itemKey);
        }

        return objectMap;
    }


}
